import math
import random
from starfield import NameGenerator
from starfield import Planet
from mathutils import Vector
import starfield

class Star:
	def __init__(self, name, location = Vector([0.0, 0.0, 0.0])):
		
		try:
			self.id = starfield.GameMaster.get_new_id()
		except:
			pass
		
		self.location = location
		
		self.connections = []
		self.planets = {}
		self.name = name
		self.mass = random.randint(5000, 10000)
		
		self.galaxy = starfield.galaxy
		
		# nice to know what I am #
		self.role = "star"
		
		self.object = 0
		
	def serialize(self, unknown=0):
		return [self.id, self.name, list(self.location)]
		
	def unpack(self, pack):
		self.id = pack[0]
		self.name = pack[1]
		self.location = pack[2]

		
	def connectedInRange(self, dist):
			inRange = {}
			newBranches = {}
			
			for branch in self.connections:
				inRange[branch.name] = branch

			for i in range(dist):
				for x in newBranches:
					inRange[x] = newBranches[x]
				for branch in inRange:
					for branch2 in inRange[branch].connections:
						newBranches[branch2.name] = branch2
						
			return inRange
	
	def getDistance(self, other):
			return math.sqrt(((other.location[0] - self.location[0]) * (other.location[0] - self.location[0])) + ((self.location[1] - other.location[1]) * (self.location[1] - other.location[1])) + ((other.location[2] - self.location[2]) * (other.location[2] - self.location[2])))
			
	def connectionsBetween(self, other):
		branches1 = []
		branches2 = []
		
		for star in self.connections:
			branches1.append(star)
		
		distance = 1
		
		while other not in branches1:

			for branch in branches2:
				branches1.append(branch)

			for branch in branches1:
				for connection in branch.connections:
					if connection not in branches1:
						branches2.append(connection)
			
			distance += 1
		
		return distance
		
	### Arguments for planet generation
	# seed = numer assigned to python's random number generator
	# scale = minimum distance between stars, in blender units
	def generatePlanets(self, seed):
		system = {}
		self.planetlist = []
		#random.seed(seed)
		
		size_min = 1
		size_max = 12
		size = random.randint(size_min, size_max)
		self.size = size
		
		minDistance = 500 * starfield.SCALE
		spacing = 250 * starfield.SCALE
		spaces = list(range(size_max))
		
		def randRotate(radius):
			angle = random.random() * 2 * math.pi
			x = radius * math.cos(angle)
			y = radius * math.sin(angle)
			z = 0.0
			return Vector([x, y, z])
		
		# Potential to have opposite rotation as it's parent (10%)
		def addRotation():
			
			starRot = self.rotation
			x = random.random()
			
			if x > .1 :
				return starRot
			
			elif starRot == 1:
				return -1
			
			else:
				return 1
		
		for i in range(size):
			# generate a name
			name = self.galaxy.namer.getName()
			
			# pick an open spot
			space = random.choice(spaces)
			spaces.remove(space)
			
			# what is the radius ?
			radius = space * spacing + minDistance
			
			# add some rotation, and finally, add that on to the star's location
			location = randRotate(radius) + self.location
			
			# let's actually make the planet
			planet = Planet.Planet(name, location)
			
			# let's give it some rotation !
			planet.rotation = addRotation()
			
			# Who's yo daddy?
			planet.star = self
			
			# now let's actually make the planet, and add it to the system dictionary
			system[name] = planet
			
			self.planetlist.append(planet)
			
		self.planets = system
		return system